package cn.good.yan.sf.t2;

import java.util.Arrays;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.stream.IntStream;

/**
 * 2.数组 - 初始化 - 版本
 * （插入、遍历 、删除、扩容）
 *
 * @author shengren.yan
 * @create 2024-04-15
 */
public class Demo2 implements Iterable<Integer> {

    private int size = 0;   // 数组的个数
    private int num = 10;   // 数组的容量
    private int[] arr = new int[num];  // 初始化数组
//    private int[] arr = null;  // 初始化数组 - 懒加载模式

    /**
     * 添加对象
     *
     * @param element 添加的对象
     * @return
     */
    public void add(int element) {
        // 扩容
//        kr();
//        arr[size] = element;
//        size++;
        add(element, size); // 往最后size添加
    }

    private void kr() {
        // 懒加载模式
        if (size == 0) {
            arr = new int[num];
        }
        if (size >= num) {
            num += num >> 1;
            int[] newArr = new int[num];
            System.arraycopy(arr, 0, newArr, 0, size);
            arr = newArr;
        }
    }

    /**
     * 添加对象 （指定下标的位置 进行创建对象）
     *
     * @param element 添加的对象
     * @param index   下标
     * @return
     */
    public void add(int element, int index) {
        // 例子：
        // int[] arr = new int[]{1,2,3}
        // int[] arr = new int[]{1,[5],2,3}
        // index = 1   新数组从 1+1=2，开始，拷贝个数：3-1=2，拷贝2个（2,3）
        if (index >= 0 && index < size) {
            // 扩容
            kr();
            // 参数1：原数组 ，
            // 参数2：原数组的下标 ，
            // 参数3：新的数据 ，
            // 参数4：要拷贝的位置，
            // 参数5：拷贝的个数
            System.arraycopy(arr, index, arr, index + 1, size - index);
        }
        arr[index] = element;
        size++;
    }

    /**
     * 获取单条
     *
     * @param index 下标
     * @return
     */
    public int get(int index) {
        // 这里少判断index的合法值
        return arr[index];
    }

    // 遍历方式1
    public void foreach() {
        for (int i = 0; i < size; i++) {
            System.out.println(arr[i]);
        }
    }

    // 遍历方式2
    public void foreach2(Consumer<Integer> consumer) {
        for (int i = 0; i < size; i++) {
            consumer.accept(arr[i]);
        }
    }

    // 遍历方式3
    public IntStream foreach3() {
        int[] ints = Arrays.copyOf(arr, size);
        return IntStream.of(ints);
    }

    // 遍历方式4
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            int i = 0;

            @Override
            public boolean hasNext() {
                // 判断是否有下一个元素
                return i < size;
            }

            @Override
            public Integer next() {
                // 获取当前元素，并移动下一个元素
                return arr[i++];
            }
        };
    }

    // 删除 - 根据下标进行删除元素
    private int remove(int index) {
        // int[] arr = new int[]{1,[5],2,3}
        // int[] arr = new int[]{1,2,3}   下标 1  size 4
        int element = get(index);
        if (index < size - 1) {
            System.arraycopy(arr, index + 1, arr, index, size - index - 1);
        }
        size--;
        return element;
    }

    public static void main(String[] args) {
        // 演示 add 方法
        Demo2 demo1 = new Demo2();
        demo1.add(1);
        demo1.add(2);
        demo1.add(3);
        demo1.add(5, 1);
        System.out.println(demo1);

        // 获取下标是1的数值
        int i = demo1.get(0);
        System.out.println(i);
        int i2 = demo1.get(2);
        System.out.println(i2);

        System.out.println("遍历：方式1 --------");
        // 遍历1：
//        demo1.foreach();
        // 遍历2：
//        demo1.foreach2(x -> {
//            System.out.println(x);
//        });
        // 遍历3：
//        demo1.foreach3().forEach(x -> {
//            System.out.println(x);
//        });
        // 遍历4：
//        for (Integer e : demo1) {
//            System.out.println(e);
//        }

        // 删除
//        int remove = demo1.remove(1);
//        System.out.println("删除" + remove);
//        demo1.foreach();

        // 扩容,  查看整体数组的长度
        for (int j = 8; j < 15; j++) {
            demo1.add(j);
        }
        System.out.println(demo1);

    }

}
